package com.lujieni.idempotent.core.keyresolver.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.lujieni.idempotent.core.annotation.Idempotent;
import com.lujieni.idempotent.core.keyresolver.IdempotentKeyResolver;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;

import java.lang.reflect.Method;

/**
 * 默认（全局级别）幂等 Key 解析器，使用方法名 + 方法参数，组装成一个 Key
 *
 * 为了避免 Key 过长，使用 MD5 进行“压缩”
 *
 * @author 芋道源码
 */
@Slf4j
public class DefaultIdempotentKeyResolver implements IdempotentKeyResolver {

    // LocalVariableTableParameterNameDiscoverer线程安全
    private static final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

    @Override
    public String resolver(ProceedingJoinPoint joinPoint, Idempotent idempotent) {
        String methodName = joinPoint.getSignature().toString();
        String argsStr = StrUtil.join(",", joinPoint.getArgs());
        MethodSignature signature = (MethodSignature)(joinPoint.getSignature());
        Method method = signature.getMethod();
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        log.info("DefaultIdempotentKeyResolver parameterNames:{}", JSONUtil.toJsonStr(parameterNames));
        log.info("DefaultIdempotentKeyResolver argsStr:{}", argsStr);
        return SecureUtil.md5(methodName + argsStr);
    }

}
